package com.lvcoding.auth2.auth.shizhan.filter;

import cn.hutool.extra.spring.SpringUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lvcoding.auth2.auth.shizhan.exception.ValidateCodeException;
import com.lvcoding.auth2.auth.shizhan.security.CustomAuthenticationEntryPoint;
import com.lvcoding.auth2.auth.shizhan.verifycode.parent.VerifyCodeHandler;
import com.lvcoding.auth2.auth.shizhan.verifycode.sms.SmsCode;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 请求过滤器,校验验证码
 *
 * @author wuyanshen
 */
@Component
public class ValidateCodeFilter extends OncePerRequestFilter {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();
    @Autowired
    private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

    @SneakyThrows
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
        String requestURI = request.getRequestURI();

        // 请求白名单
        String[] whiteList = {
                "/oauth/token",
        };

        // 如果不是登录请求就放行
        boolean anyMatch = Arrays.stream(whiteList).anyMatch(url -> antPathMatcher.match(url, requestURI));
        if (!anyMatch) {
            filterChain.doFilter(request, response);
            return;

        }

        String grantType = request.getParameter("grant_type");
        if (!"mobile".equals(grantType)) {
            filterChain.doFilter(request, response);
            return;
        }

        // 校验验证码
        try {
            checkCode(request);
        } catch (ValidateCodeException exception) {
            customAuthenticationEntryPoint.commence(request, response, exception);
            return;
        }

        filterChain.doFilter(request, response);
    }

    private void checkCode(HttpServletRequest request) {
        RedisTemplate<String, Object> redisTemplate = SpringUtil.getBean("redisTemplate");

        // 参数中的验证码
        String code = request.getParameter("code");

        if (code == null) {
            throw new ValidateCodeException("验证码不能为空");
        }

        // redis中的验证码
        SmsCode smsCode = (SmsCode) redisTemplate.opsForValue().get(VerifyCodeHandler.VERIFY_CODE_KEY + "sms");
        if (smsCode == null) {
            throw new ValidateCodeException("验证码已失效");
        }

        String codeRedis = smsCode.getCode();

        if (!code.equals(codeRedis)) {
            throw new ValidateCodeException("验证码无效");
        }

    }
}
